package com.jplus.core.mvc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import com.jplus.core.core.AnnotationConfigApplicationContext;
import com.jplus.core.core.beans.BeanDefinition;
import com.jplus.core.core.beans.BeanKey;
import com.jplus.core.fault.BeansException;
import com.jplus.core.fault.InitializationError;
import com.jplus.core.mvc.anno.Controller;
import com.jplus.core.mvc.response.defaults.JSONResponseHandle;
import com.jplus.core.mvc.response.defaults.JSPResponseHandle;
import com.jplus.core.utill.Assert;
import com.jplus.core.utill.clazz.ClassUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * WebApplicationContext
 * 
 * @author Yuanqy
 *
 */
public class AnnotationConfigWebApplicationContext extends AnnotationConfigApplicationContext {
	private final Logger log = LoggerFactory.getLogger(AnnotationConfigWebApplicationContext.class);
	private ServletContext servletContext;

	private String defaultServletName = "default";
	private List<String> defaultServletMapping = new ArrayList<>();

	private Map<String, BeanKey> rmBean = new HashMap<>();
	private Map<String, RequestMethodAttr> rmMethod = new HashMap<>();

	public void start() throws InitializationError {
		try {
			registerDefBean();
			// 3.init Context
			super.refresh();
			// 4.prepareMapping
			registerMapping();
		} catch (Exception e) {
			log.error("InitializationError", e);
			throw new InitializationError(e);
		}
		log.info("##### Jplus Web Frame start is completed. #####\n");
	}
	// ================================================================

	private void registerDefBean() {
		// 设置默认视图，用户可自定义覆盖，@Order>10
		super.registerBean(JSONResponseHandle.class);
		super.registerBean(JSPResponseHandle.class);
	}

	private void registerMapping() {
		log.info("[ACTION]:");
		List<BeanDefinition> list = beanDefinition.listSortBeanDefinitions();
		for (BeanDefinition bd : list) {
			boolean c = ClassUtil.hasAnnotation(bd.getBeanClass(), Controller.class);
			if (c) {
				List<RequestMethodAttr> listAttr = RequestMethodAttr.build(bd.getBeanClass());
				for (RequestMethodAttr rma : listAttr) {
					rmBean.put(rma.requestMapping, bd.getBeanKey());
					rmMethod.put(rma.requestMapping, rma);
				}
			}
		}
	}

	public BeanKey getRmBean(String requestPath) {
		return rmBean.get(requestPath);
	}

	public RequestMethodAttr getRmMethod(String requestPath) {
		return rmMethod.get(requestPath);
	}

	public Map<String, BeanKey> getRmBean() {
		return rmBean;
	}

	public ServletContext getServletContext() {
		return servletContext;
	}

	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	@Override
	protected void postProcessImportClass()
			throws InstantiationException, IllegalAccessException, BeansException, ClassNotFoundException {
		super.postProcessImportClass();
		// ==HandlerInterceptor ==========================
		List<BeanDefinition> list = getBeanDefinitions().listSortBeanDefinitions();
		// 1.找到所有的HandlerInterceptor
		List<BeanKey> interceptors = new ArrayList<>();
		for (BeanDefinition en : list) {
			if (HandlerInterceptorAdapter.class.isAssignableFrom(en.getBeanClass())) {
				interceptors.add(en.getBeanKey());
				log.info("[HandlerInterceptor]>>{}", en.getBeanKey());
			}
		}
		// 2.找到所有的Action TODO 待优化
		for (BeanDefinition bd : list) {
			if (ClassUtil.hasAnnotation(bd.getBeanClass(), Controller.class)) {
				for (BeanKey beanKey : interceptors) {
					bd.addProxyList(beanKey);// 为所有Action添加代理类
				}
			}
		}
	}

	public void setDefaultServletName(String defaultServlet) {
		Assert.notNull(defaultServlet);
		defaultServletName = defaultServlet;
	}

	public void setDefaultServletMapping(String... resources) {
		Assert.notNull(resources);
		for (String pair : resources)
			defaultServletMapping.add(pair);
	}

	public String getDefaultServletName() {
		return defaultServletName;
	}

	public List<String> getDefaultServletMapping() {
		return defaultServletMapping;
	}

}
